package com.woniuxy.yoga.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alipay.api.domain.StoreInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.business.client.CourseClient;
import com.woniuxy.yoga.business.dao.mapper.BusinessAccountMapper;
import com.woniuxy.yoga.business.dao.mapper.BusinessStoreMapper;
import com.woniuxy.yoga.business.dao.model.BusinessAccount;
import com.woniuxy.yoga.business.dao.model.BusinessStore;
import com.woniuxy.yoga.business.dao.model.StoreClassroom;
import com.woniuxy.yoga.business.dao.mapper.StoreClassroomMapper;
import com.woniuxy.yoga.business.model.dto.course.OrdinaryCourseDTO;
import com.woniuxy.yoga.business.model.dto.storeclassroom.*;
import com.woniuxy.yoga.business.model.exception.BusinessException;
import com.woniuxy.yoga.business.model.exception.BusinessExceptionCode;
import com.woniuxy.yoga.business.model.param.storeclassroom.*;
import com.woniuxy.yoga.business.service.BusinessStoreService;
import com.woniuxy.yoga.business.service.StoreClassroomService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.BusinessState;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 门店教室表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class StoreClassroomServiceImpl extends ServiceImpl<StoreClassroomMapper, StoreClassroom> implements StoreClassroomService {

    @Autowired
    private BusinessAccountMapper businessAccountMapper;
    @Autowired
    private StoreClassroomMapper storeClassroomMapper;
    @Autowired
    private BusinessStoreMapper businessStoreMapper;
    @Autowired
    private BusinessStoreService businessStoreService;
    @Autowired
    private CourseClient courseClient;
    /**
     * 新增门店教室
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public StoreClassroomAddDTO addStoreClassroom(StoreClassroomAddParam param) {
        //查询商家账号是否存在
        BusinessAccount businessAccount = businessAccountMapper.selectById(param.getAddUserId());
        if (businessAccount==null) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        }
        //商家账号状态是否正常
        if (businessAccount.getAccountState()!= BusinessState.BUSINESS_ACCOUNT_STATE_NORMAL) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_ACCOUNT_STATEERROR);
        }
        //查询商家的门店信息
        LambdaQueryWrapper<BusinessStore> storeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeLambdaQueryWrapper.eq(BusinessStore::getAccountId,param.getAddUserId())
                .notIn(BusinessStore::getStoreState,BusinessState.STORE_STATE_DELETE);
        BusinessStore businessStore = businessStoreMapper.selectOne(storeLambdaQueryWrapper);
        if (businessStore==null) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_BUSINESS_NOTHASSTORE);
        }
        param.setStoreId(businessStore.getStoreId());
        //教室名是否存在
        LambdaQueryWrapper<StoreClassroom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreClassroom::getClassroomName,param.getClassroomName())
                .eq(StoreClassroom::getStoreId,businessStore.getStoreId());
        StoreClassroom oneStoreClassroom = storeClassroomMapper.selectOne(queryWrapper);
        if (oneStoreClassroom!=null) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOMNAME_EXITS);
        }
        //团课教室数量只能为一个
        if (param.getClassroomType()== BusinessState.CLASSROOM_TYPE_TEAM) {
            LambdaQueryWrapper<StoreClassroom> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreClassroom::getClassroomType,BusinessState.CLASSROOM_TYPE_TEAM)
                    .eq(StoreClassroom::getStoreId,businessStore.getStoreId());
            StoreClassroom storeClassroom = storeClassroomMapper.selectOne(wrapper);
            if (storeClassroom!=null) {
                throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_TEAMCLASSROOM_EXITS);
            }
        }
        //将教室插入到数据库中
        StoreClassroom storeClassroom = BeanUtil.toBean(param, StoreClassroom.class);
        storeClassroom.setClassroomState(BusinessState.CLASSROOM_STATE_NORMAL);
        storeClassroom.setAddUser(businessAccount.getAccountName());
        storeClassroom.setAddTime(DateUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));
        storeClassroomMapper.insert(storeClassroom);
        return BeanUtil.toBean(storeClassroom,StoreClassroomAddDTO.class);
    }

    /**
     * 修改门店教室信息
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public StoreClassroomUpdateDTO updateStoreClassroom(StoreClassroomUpdateParam param) {
        //查询教室是否存在
        StoreClassroom storeClassroom = storeClassroomMapper.selectById(param.getClassroomId());
        if (storeClassroom==null)throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_NOTEXITS);
        //教室状态是否正常
        if (storeClassroom.getClassroomState()!=BusinessState.CLASSROOM_STATE_NORMAL)throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_STATEERROR);
        //查询商家账号是否存在
        BusinessAccount businessAccount = businessAccountMapper.selectById(param.getUpdateUserId());
        if (businessAccount==null) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_ACCOUNT_NOTEXITS);
        }
        //商家账号状态是否正常
        if (businessAccount.getAccountState()!= BusinessState.BUSINESS_ACCOUNT_STATE_NORMAL) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_ACCOUNT_STATEERROR);
        }
        //查询商家的门店信息
        LambdaQueryWrapper<BusinessStore> storeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeLambdaQueryWrapper.eq(BusinessStore::getAccountId,businessAccount.getAccountId())
                .notIn(BusinessStore::getStoreState,BusinessState.STORE_STATE_DELETE);
        BusinessStore businessStore = businessStoreMapper.selectOne(storeLambdaQueryWrapper);
        if (businessStore==null) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_BUSINESS_NOTHASSTORE);
        }
        //教室名是否存在
        LambdaQueryWrapper<StoreClassroom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoreClassroom::getClassroomName,param.getClassroomName())
                .eq(StoreClassroom::getStoreId,businessStore.getStoreId())
                .notIn(StoreClassroom::getClassroomId,param.getClassroomId());
        StoreClassroom oneStoreClassroom = storeClassroomMapper.selectOne(queryWrapper);
        if (oneStoreClassroom!=null) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOMNAME_EXITS);
        }
        //团课教室数量只能为一个
        if (param.getClassroomType()== BusinessState.CLASSROOM_TYPE_TEAM) {
            LambdaQueryWrapper<StoreClassroom> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreClassroom::getClassroomType,BusinessState.CLASSROOM_TYPE_TEAM)
                    .eq(StoreClassroom::getStoreId,businessStore.getStoreId())
                    .notIn(StoreClassroom::getClassroomId,param.getClassroomId());
            StoreClassroom twoStoreClassroom = storeClassroomMapper.selectOne(wrapper);
            if (twoStoreClassroom!=null) {
                twoStoreClassroom.setClassroomType(BusinessState.CLASSROOM_TYPE_NORMAL);
                storeClassroomMapper.updateById(twoStoreClassroom);
            }
        }
        //修改数据库中的教室信息
        storeClassroom.setClassroomName(param.getClassroomName());//修改教室名
        storeClassroom.setClassroomMax(param.getClassroomMax());//修改教室容量
        storeClassroom.setClassroomType(param.getClassroomType());//修改教室类型
        storeClassroom.setUpdateTime(DateUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));
        storeClassroom.setUpdateUser(businessAccount.getAccountName());
        storeClassroomMapper.updateById(storeClassroom);
        return BeanUtil.toBean(storeClassroom,StoreClassroomUpdateDTO.class);
    }

    /**
     * 删除门店教室
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void deleteStoreClassroom(StoreClassroomDeleteParam param) {
        //查询教室是否存在
        StoreClassroom storeClassroom = storeClassroomMapper.selectById(param.getClassroomId());
        if (storeClassroom==null)throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_NOTEXITS);
        //教室状态不能为删除状态
        if (storeClassroom.getClassroomState()==BusinessState.CLASSROOM_STATE_DELETE)throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_STATEERROR);
        //判断有没有课程在该教室上课（还有课则不能删除）
        Result<List<OrdinaryCourseDTO>> courseResult = courseClient.getByClassroomId(param.getClassroomId());
        if (courseResult.getCode()==500) {
            throw new BusinessException(500,"系统异常");
        }
        if (courseResult.getCode()!=200) {
            throw new BusinessException(courseResult.getCode(),courseResult.getMessage());
        }
        List<OrdinaryCourseDTO> ordinaryCourseDTOS = courseResult.getData();
        //若有课程
        if (ordinaryCourseDTOS!=null&&ordinaryCourseDTOS.size()>0) {
            //查看该课程课程结束时间是否在当前之后
            for (OrdinaryCourseDTO ordinaryCourseDTO : ordinaryCourseDTOS) {
                LocalDateTime now = LocalDateTime.now();
                LocalDateTime endTime = DateUtil.parseLocalDateTime(ordinaryCourseDTO.getCourseEndDate());
                if (endTime.isAfter(now)) {
                    throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_ORDER_NOTCOMPLETED);
                }
            }
        }
        //修改数据库中的教室状态
        BusinessAccount businessAccount = businessAccountMapper.selectById(param.getAccountId());
        storeClassroom.setClassroomState(BusinessState.CLASSROOM_STATE_DELETE);
        storeClassroom.setUpdateUser(businessAccount.getAccountName());
        storeClassroom.setUpdateTime(DateUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss"));
        storeClassroomMapper.updateById(storeClassroom);
    }

    /**
     * 分页查询门店所有教室
     * @param param
     * @return
     */
    @Override
    public PageInfo selectPageStoreClassroomInfo(StoreSelectClassroomPageParam param) {
        //查看门店是否存在
        BusinessStore businessStore = businessStoreService.getOne(new LambdaQueryWrapper<BusinessStore>().eq(BusinessStore::getAccountId,param.getAccountId()));
        if (businessStore == null) throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_STORE_NOTEXITS);
        //门店状态是否正常
        if (businessStore.getStoreState()==BusinessState.STORE_STATE_DELETE) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_STORE_STATEERROR);
        }
        //创建分页查询对象
        Page<StoreClassroom> page = new Page<StoreClassroom>(param.getCurrent()==null?1:param.getCurrent(),
                param.getSize()==null?10:param.getSize());
        LambdaQueryWrapper<StoreClassroom> wrapper = new LambdaQueryWrapper<StoreClassroom>();
        wrapper.eq(StoreClassroom::getClassroomState,BusinessState.CLASSROOM_STATE_NORMAL).
                eq(StoreClassroom::getStoreId,businessStore.getStoreId());
        Page<StoreClassroom> storeInfoPage = storeClassroomMapper.selectPage(page, wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setRecords(BeanUtil.copyToList(storeInfoPage.getRecords(), StoreClassroomSelectDTO.class));
        pageInfo.setPages(page.getPages());
        return pageInfo;
    }

    /**
     *查询所有的教室，并按 id->详情 存储
     * @param param
     * @return
     */
    @Override
    public Map<Integer, ClassroomNormalDto> selNormalByIds(StoreClassroomIdsParam param) {
        //查询门店拥有的所有正常状态下的教室
        List<StoreClassroom> storeRooms = storeClassroomMapper.selectList(new LambdaQueryWrapper<StoreClassroom>().
                eq(StoreClassroom::getStoreId, param.getStoreId()).eq(StoreClassroom::getClassroomState,BusinessState.CLASSROOM_STATE_NORMAL));
        //若给定的集合中不在范围内则抛异常
        boolean bool = storeRooms.stream().map(storeRoom->storeRoom.getClassroomId()).collect(Collectors.toList()).containsAll(param.getClassroomIds());
        if (bool){
            //将正常教室的信息存入map集合中
            Map<Integer, ClassroomNormalDto> dtoMap = new HashMap<>();
            List<StoreClassroom> rooms = storeClassroomMapper.selectBatchIds(param.getClassroomIds());
            for (StoreClassroom room : rooms) {
                dtoMap.put(room.getClassroomId(),BeanUtil.toBean(room,ClassroomNormalDto.class));
            }
            return dtoMap;
        }else throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_STATEERROR);
    }

    /**
     *根据教室id查询教室信息
     * @param storeClassroomId
     * @return
     */
    @Override
    public StoreClassroomByIdDTO selNormalById(Integer storeClassroomId) {
        //查询该教室是否存在
        StoreClassroom storeClassroom = storeClassroomMapper.selectOne(new LambdaQueryWrapper<StoreClassroom>().eq(StoreClassroom::getClassroomId, storeClassroomId));
        if (storeClassroom==null)throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_NOTEXITS);
        //教室状态是否正常
        if (storeClassroom.getClassroomState()!=BusinessState.CLASSROOM_STATE_NORMAL)throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_STATEERROR);
        //返回正常的教室信息
        return BeanUtil.toBean(storeClassroom,StoreClassroomByIdDTO.class);
    }

    /**
     *商家查询门店所有可用教室
     * @param businessId
     * @return
     */
    @Override
    public List<ClassroomNormalDto> getAllNormalClassroomsByBusinessId(Integer businessId) {
        //门店是否存在
        BusinessStore businessStore = businessStoreService.getOne(new LambdaQueryWrapper<BusinessStore>().eq(BusinessStore::getAccountId,businessId));
        if (businessStore == null) throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_STORE_NOTEXITS);
        //门店状态是否正常
        if (businessStore.getStoreState()!=BusinessState.STORE_STATE_NORMAL) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_STORE_STATEERROR);
        }
        //是否已经缴纳入驻费
        if (businessStore.getEnterMoneyState()!=BusinessState.ENTER_MONEY_STATE_PAYED) {
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_PAYMENT_NOTPAY);
        }
        //返回教室信息集合
        LambdaQueryWrapper<StoreClassroom> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreClassroom::getStoreId,businessStore.getStoreId());
        wrapper.eq(StoreClassroom::getClassroomState,BusinessState.CLASSROOM_STATE_NORMAL);
        List<StoreClassroom> storeClassrooms = list(wrapper);
        return BeanUtil.copyToList(storeClassrooms, ClassroomNormalDto.class);
    }

    /**
     * 禁用教室
     * @param classroomId classroomId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableClassroom(Integer classroomId) {
        //查询教室
        StoreClassroom storeClassroom = storeClassroomMapper.selectById(classroomId);
        if (storeClassroom==null) throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_NOTEXITS);
        if (!Objects.equals(storeClassroom.getClassroomState(), BusinessState.CLASSROOM_STATE_NORMAL))
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_STATEERROR);
        //修改状态
        storeClassroom.setClassroomState(BusinessState.CLASSROOM_STATE_DISABLE);
        storeClassroomMapper.updateById(storeClassroom);
    }

    /**
     * 启用教室
     * @param classroomId classroomId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enableClassroom(Integer classroomId) {
        //查询教室
        StoreClassroom storeClassroom = storeClassroomMapper.selectById(classroomId);
        if (storeClassroom==null) throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_NOTEXITS);
        if (!Objects.equals(storeClassroom.getClassroomState(), BusinessState.CLASSROOM_STATE_DISABLE))
            throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_STATEERROR);
        //修改状态
        storeClassroom.setClassroomState(BusinessState.CLASSROOM_STATE_NORMAL);
        storeClassroomMapper.updateById(storeClassroom);
    }

    /**
     * 查询商家可用教室
     * @param storeId 门店id
     * @return List<ClassroomNormalDto>
     */
    @Override
    public List<ClassroomNormalDto> findUsefulClassroom(Integer storeId) {
        //验证门店id
        BusinessStore businessStore = businessStoreMapper.selectById(storeId);
        if (businessStore==null) throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_STORE_NOTEXITS);
        QueryWrapper<StoreClassroom> wrapper = new QueryWrapper<>();
        wrapper.eq("store_id",storeId);
        wrapper.eq("classroom_state",BusinessState.CLASSROOM_STATE_NORMAL);
        List<StoreClassroom> storeClassrooms = storeClassroomMapper.selectList(wrapper);
        if (storeClassrooms.size()==0) throw new BusinessException(BusinessExceptionCode.BUSINESS_EXCEPTION_CODE_CLASSROOM_NOTEXITS);
        return BeanUtil.copyToList(storeClassrooms, ClassroomNormalDto.class);
    }
}
